package deibay.server.backend.core;


import java.util.HashMap;
import java.util.LinkedList;
import java.util.logging.Level;

import deibay.DeibayLogger;
import deibay.server.events.BiddingItemEvent;
import deibay.server.events.Event;
import deibay.server.events.GetItemEvent;
import deibay.server.events.GetItemsListEvent;
import deibay.server.events.GetSellerItemEvent;
import deibay.server.events.GetSellerItemsListEvent;
import deibay.server.events.LoggoutEvent;
import deibay.server.events.NewItemEvent;
import deibay.server.events.NotifyBiddingItemEvent;
import deibay.server.events.NotifyDeadlineItemEvent;
import deibay.server.events.PongEvent;
import deibay.server.events.ReauthenticateEvent;
import deibay.server.events.RemoveItemEvent;
import deibay.server.events.RemoveSessionEvent;
import deibay.server.events.ReplyBiddingItemEvent;
import deibay.server.events.ReplyGetItemEvent;
import deibay.server.events.ReplyGetSellerItemEvent;
import deibay.server.events.ReplyGetSellerItemsListEvent;
import deibay.server.events.ReplyItemsListEvent;
import deibay.server.events.ReplySubscribeItemEvent;
import deibay.server.events.SaveMessageEvent;
import deibay.server.events.SendAdvertiseEvent;
import deibay.server.events.SendMessageEvent;
import deibay.server.events.SubscribeItemEvent;


public class EventManager {	
		
	private HashMap<Class, LinkedList<EventConsumer>> listeners = null;	
	
	public EventManager()
	{
		try
		{
			listeners = new HashMap<Class, LinkedList<EventConsumer>>();						
		}
		catch (Exception exc)
		{			
			DeibayLogger.getInstance().getLog().log(Level.SEVERE, "" + exc.getMessage());		
		}		
	}
	
	public void init()
	{
		publish();	
	}
	
	public synchronized void fireEvent(final Event event)
	{	
		Thread processEvents = new Thread(new ProcessEvents(event, listeners));
		processEvents.start();				
		DeibayLogger.getInstance().getLog().log(Level.WARNING, "Foi disparado o evento "+event.toString()+".\n");
	}
	
	public void publish()
	{	
		listeners.put(BiddingItemEvent.class, new LinkedList<EventConsumer>());	
		listeners.put(SubscribeItemEvent.class, new LinkedList<EventConsumer>());		
		listeners.put(NewItemEvent.class, new LinkedList<EventConsumer>());	
		listeners.put(GetItemEvent.class, new LinkedList<EventConsumer>());
		listeners.put(GetItemsListEvent.class, new LinkedList<EventConsumer>());
		listeners.put(GetSellerItemsListEvent.class, new LinkedList<EventConsumer>());
		listeners.put(RemoveSessionEvent.class, new LinkedList<EventConsumer>());
		listeners.put(PongEvent.class, new LinkedList<EventConsumer>());
		listeners.put(ReplyBiddingItemEvent.class, new LinkedList<EventConsumer>());
		listeners.put(NotifyBiddingItemEvent.class, new LinkedList<EventConsumer>());
		listeners.put(ReplyItemsListEvent.class, new LinkedList<EventConsumer>());
		listeners.put(ReplyGetItemEvent.class, new LinkedList<EventConsumer>());
		listeners.put(RemoveItemEvent.class, new LinkedList<EventConsumer>());		
		listeners.put(NotifyDeadlineItemEvent.class, new LinkedList<EventConsumer>());
		listeners.put(GetSellerItemEvent.class, new LinkedList<EventConsumer>());		
		listeners.put(ReplyGetSellerItemEvent.class, new LinkedList<EventConsumer>());
		listeners.put(ReplyGetSellerItemsListEvent.class, new LinkedList<EventConsumer>());
		listeners.put(SendMessageEvent.class, new LinkedList<EventConsumer>());
		listeners.put(ReauthenticateEvent.class, new LinkedList<EventConsumer>());
		listeners.put(ReplySubscribeItemEvent.class, new LinkedList<EventConsumer>());
		listeners.put(SaveMessageEvent.class, new LinkedList<EventConsumer>());
		listeners.put(LoggoutEvent.class, new LinkedList<EventConsumer>());
		listeners.put(SendAdvertiseEvent.class, new LinkedList<EventConsumer>());
	}
	
	public synchronized void unPublish(Class event)
	{
		listeners.remove(event);
	}
	
	public synchronized void subscribe(final EventConsumer consumer, Class event)
	{
		LinkedList<EventConsumer> consumers = listeners.get(event);
		consumers.add(consumer);
		DeibayLogger.getInstance().getLog().log(Level.INFO, "Consumidor ["+consumer.getClass().getCanonicalName()+"] inscreveu-se ao evento ["+event.getCanonicalName()+"].\n");
	}
	
	public synchronized void unSubscribe(EventConsumer consumer, Class event)
	{
		LinkedList consumers = listeners.get(event);
		consumers.remove(consumer);		
	}
}
